#include "CTLParser.hh"
#include <stdlib.h>

AST::AST (symbols	value)
{
  value_ = value;
  var_value_ = std::string ();
  sons_ = NULL;
  nb_sons_ = 0;
}

AST::AST (std::string	value)
{
  value_ = VAR;
  var_value_ = value;
  sons_ = NULL;
  nb_sons_ = 0;
}

AST*
AST::getIthSon (unsigned i)
{
  if (i < nb_sons_)
    return sons_[i];
  return NULL;
}

void
AST::setSons (AST**	sons,
	      unsigned	nb)
{
  sons_ = sons;
  nb_sons_ = nb;
}

void
AST::print (unsigned offset)
{
  for (unsigned i = 0 ; i < offset; ++i)
    std::cout << " ";

  std::cout << "Valeur du noeud = " << value_ << ", ";
  if (value_ == VAR)
    std::cout << "valeur de la variable = " << var_value_ << ", ";
  std::cout << "nombre de fils = " << nb_sons_ << ";" << std::endl;

  for (unsigned i = 0; i < nb_sons_; ++i)
    this->getIthSon(i)->print (offset + 1);
}


symbols
AST::getValue ()
{
  return value_;
}


std::string
AST::getVariable ()
{
  return var_value_;
}

AST**
parseNargs (CTLLexer &lex,
	    unsigned argc)
{
  AST** res = new AST*[argc];
  symbols token;
  if ((token = lex.getNextToken ()) != LPAR)
    {
      std::cout << "Parse error : expected '('" << std::endl;
      exit (1);
    }
  for (unsigned i = 0; i < argc; ++i)
    {
      res[i] = parseCTL (lex);
      if ((i != argc - 1) && ((token = lex.getNextToken ()) != COMMA))
	{
	  std::cout << "Parse error : expected ','" << std::endl;
	  exit (1);
	}
    }
  if ((token = lex.getNextToken ()) != RPAR)
    {
      std::cout << "Parse error : expected ')'" << std::endl;
      exit (1);
    }
  return res;
}


AST*
parseCTL (CTLLexer &lex)
{
  symbols token;

  token = lex.getNextToken ();

  if (token == AND)
    {
      AST** res = parseNargs (lex, 2);
      AST* result = new AST (AND);
      result->setSons (res, 2);
      return result;
    }

  if (token == OR)
    {
      AST** res = parseNargs (lex, 2);
      AST* result = new AST (OR);
      result->setSons (res, 2);
      return result;
    }

  if (token == NOT)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (NOT);
      result->setSons (res, 1);
      return result;
    }

  if (token == IMPLIES)
    {
      AST** res = parseNargs (lex, 2);
      AST* result = new AST (IMPLIES);
      result->setSons (res, 2);
      return result;
    }

  if (token == EX)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (EX);
      result->setSons (res, 1);
      return result;
    }

  if (token == AX)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (AX);
      result->setSons (res, 1);
      return result;
    }

  if (token == EF)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (EF);
      result->setSons (res, 1);
      return result;
    }

  if (token == AF)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (AF);
      result->setSons (res, 1);
      return result;
    }

    if (token == EG)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (EG);
      result->setSons (res, 1);
      return result;
    }

  if (token == AG)
    {
      AST** res = parseNargs (lex, 1);
      AST* result = new AST (AG);
      result->setSons (res, 1);
      return result;
    }

  if (token == EU)
    {
      AST** res = parseNargs (lex, 2);
      AST* result = new AST (EU);
      result->setSons (res, 2);
      return result;
    }

  if (token == AU)
    {
      AST** res = parseNargs (lex, 2);
      AST* result = new AST (AU);
      result->setSons (res, 2);
      return result;
    }

  if (token == T)
    {
      AST* result = new AST (T);
      return (result);
    }

  if (token == F)
    {
      AST* result = new AST (F);
      return (result);
    }

  if (token == VAR)
    {
      AST* result = new AST (lex.getNextVar ());
      return result;
    }

}
